﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using System.Windows;
using Phoenix.Xna.Framework.Reflection;
using Phoenix.Xna.Framework.Graphics;

namespace Phoenix.Xna.Framework.Presentation
{
    public class EffectWrapper : DependencyObject
    {
        private Effect _effect;

        public string ID { get; set; }
        public string Asset { get; set; }
        public List<EffectTechniqueWrapper> Techniques { get; set; }
        public List<EffectWrapper> SubEffects { get; set; }
        public static readonly DependencyProperty CurrentTechniqueProperty = DependencyProperty.Register("CurrentTechnique", typeof(EffectTechniqueWrapper), typeof(EffectWrapper));
        public EffectTechniqueWrapper CurrentTechnique
        {
            get { return (EffectTechniqueWrapper)GetValue(CurrentTechniqueProperty); }
            set { SetValue(CurrentTechniqueProperty, value); }
        }

        public EffectWrapper(string id, string location, Effect effect)
        {
            ID = id;
            Asset = location;
            SubEffects = new List<EffectWrapper>();
            _effect = effect;
            ParseTechniques();
            ParseEffectParameters();
        }

        public EffectMap GenerateEffectMap()
        {
            EffectMap map = new EffectMap()
            {
                ID = ID
            };
            ReflectionHelper.SetField<EffectMap>(map, "_effectAsset", Asset);
            ReflectionHelper.SetField<EffectMap>(map, "_currentTechnique", CurrentTechnique.Name);
            TechniqueCollection techniques = new TechniqueCollection();

            foreach (EffectTechniqueWrapper t in Techniques)
            {
                techniques.Add(t.GenerateTechnique());
            }

            map.Techniques = techniques;
            return map;
        }

        private void ParseTechniques()
        {
            Techniques = new List<EffectTechniqueWrapper>();

            foreach (EffectTechnique t in _effect.Techniques)
            {
                Techniques.Add(new EffectTechniqueWrapper(t));
            }

            CurrentTechnique = Techniques[0];
        }

        private void ParseEffectParameters()
        {
            foreach (EffectTechniqueWrapper t in Techniques)
            {
                List<EffectParameterWrapper> parameters = new List<EffectParameterWrapper>();

                foreach (EffectParameter p in _effect.Parameters)
                {
                    parameters.Add(new EffectParameterWrapper(p));
                }

                t.Parameters = parameters;
            }
        }
    }
}
